home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
v10n01.arc
/
INT9.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1990-12-11
|
7KB
|
172 lines
{******************************************************************************
* *
* PC MAGAZINE'S INTERRUPT 9H READER *
* Copyright (c) 1990 Ziff Communications Co. *
* portions Copyright (c) TurboPower Software 1987 *
* written by Barry Simon *
* *
*****************************************************************************}
USES
Dos, CRT;
{the next type and the inline code in ChainInt are from Turbo Power Software's
Turbo Professional package and are used with permission}
TYPE
IntRegisters =
RECORD
BP, ES, DS, DI, SI, DX, CX, BX, AX, IP, CS, Flags : Word;
END;
VAR
CurH, CurL : Byte;
Regs : Registers;
PROCEDURE HideCursor;
BEGIN
WITH Regs DO BEGIN
AH := 3; {read cursor info}
BH := 0; {assume page 0}
intr($10, Regs);
CurH := CH; CurL := CL; {save cursor info}
AH := 1; {set Cursor Shape}
CX := $2000; {hide cursor}
intr($10, Regs);
END;
END;
PROCEDURE RestoreCursor;
BEGIN
WITH Regs DO BEGIN
CH := CurH; CL := CurL; {restore cursor info}
AH := 1; {set Cursor Shape}
intr($10, Regs);
END;
END;
PROCEDURE ChainInt(VAR Regs : IntRegisters; JumpAddr : Pointer);
{Copyright (c) TurboPower Software 1987}
{-Restores stack, registers from Regs and 'jumps' to JumpAddr}
INLINE(
$5B/ {pop bx ;BX = Ofs(JumpAddr^)}
$58/ {pop ax ;AX = Seg(JumpAddr^)}
$5E/ {pop si ;SI = Ofs(Regs)}
$1F/ {pop ds ;DS:SI => Regs}
{;Change stack so RETF passes control to JumpAddr;
restore Flags}
$87/$5C/$0E/ {xchg bx,[si+14] ;Switch old BX and Ofs(JumpAddr^)}
$87/$44/$10/ {xchg ax,[si+16] ;Switch old AX and Seg(JumpAddr^)}
$8B/$54/$16/ {mov dx,[si+22] ;Old Flags into DX}
$52/ {push dx ;Push altered flags}
$9D/ {popf ;Pop them into place}
{;Switch stacks -- make SS:SP point to Regs.BP}
$8C/$DA/ {mov dx,ds ;DX = Seg(Regs)}
$FA/ {cli ;Interrupts off}
$8E/$D2/ {mov ss,dx ;Restore SS from DX}
$89/$F4/ {mov sp,si ;Restore SP from SI}
$FB/ {sti ;Interrupts on}
$5D/ {pop bp ;Restore BP}
$07/ {pop es ;Restore ES}
$1F/ {pop ds ;Restore DS}
$5F/ {pop di ;Restore DI}
$5E/ {pop si ;Restore SI}
$5A/ {pop dx ;Restore DX}
$59/ {pop cx ;Restore CX}
{;BX and AX restored earlier; their places on stack}
{;now have JumpAddr, which is where return will go}
$CB); {retf ;Chain to JumpAddr}
CONST
HexDigits : ARRAY[0..15] OF Char = '0123456789ABCDEF';
FUNCTION ByteToHex(B : Byte) : STRING;
{Changes byte to hex string}
BEGIN
ByteToHex := HexDigits[B DIV 16]+HexDigits[B MOD 16];
END;
VAR
oldint9 : Pointer;
numkeys : Byte;
scancode : ARRAY[0..127] OF Byte; {more than 1 is needed to handle
keystrokes that produce multiple
int9's}
x, y, j : Byte;
int16regs : Registers;
PROCEDURE myint9(BP : Word); interrupt;
VAR
Regs : IntRegisters ABSOLUTE BP;
BEGIN
IF (numkeys < 128) THEN numkeys := numkeys+1;
scancode[numkeys] := Port[$60];
ChainInt(Regs, oldint9);
END;
BEGIN
textattr := $0E;
getintvec(9, oldint9);
setintvec(9, @myint9);
HideCursor;
numkeys := 0;
clrscr;
gotoXY(1, 1);
WriteLn('PC Magazine''s Int 9 key reader; Copyright (c) 1990 Ziff Communications Co. ');
WriteLn(' Hit <Esc> to Exit ');
WriteLn(' Hex ASCII Hex ASCII Hex ASCII Hex ASCII ');
WriteLn(' ------ ------- ------ ------- ------ ------- ------ ------- ');
gotoXY(1, 5);
x := 5;
WHILE True DO BEGIN
IF numkeys > 0 THEN BEGIN
y := whereY;
IF (((y > 20) AND (scancode[0] <> $E0) AND (scancode[0] <> $FA)
AND (scancode[0] > $80))
OR (y > 23)) THEN IF x < 65 THEN BEGIN
x := x+20;
y := 5;
END ELSE BEGIN
clrscr;
gotoXY(1, 1);
WriteLn('PC Magazine''s Int 9 key reader; Copyright (c) 1990 Ziff Communications Co. ');
WriteLn(' Hit <Esc> to Exit ');
WriteLn(' Hex ASCII Hex ASCII Hex ASCII Hex ASCII ');
WriteLn(' ------ ------- ------ ------- ------ ------- ------ ------- ');
gotoXY(1, 5);
x := 5;
y := 5;
END;
gotoXY(x, y);
Write(ByteToHex(scancode[1]));
gotoXY(x+8, y);
{writeln(scancode[1]:3,' ',numkeys)}
{comment in above line and out below line to explore stack; try
putting on numlock and hitting cursor keys a lot!!}
WriteLn(scancode[1]:3);
IF numkeys = 127 THEN WriteLn('Keystack Overflow!!! Program Halted');
IF (((scancode[1] MOD 128) = 1) OR (numkeys = 127)) THEN BEGIN
setintvec(9, oldint9);
WHILE keypressed DO BEGIN
int16regs.AH := 0;
intr($16, int16regs);
END;
gotoXY(1, 23);
RestoreCursor;
Halt;
END;
IF ((numkeys = 1) AND (scancode[1] <> $E0) AND (scancode[1] <> $FA)
AND (scancode[1] > $80)) THEN WriteLn;
numkeys := numkeys-1;
FOR j := 0 TO numkeys DO scancode[j] := scancode[j+1];
WHILE keypressed DO BEGIN
int16regs.AH := 0;
intr($16, int16regs);
END;
END;
END;
END.